
#pragma once

class DWORD128
{
public:
	DWORD128(){}
	DWORD128(DWORD64 v) { low = v; high = 0; }
	DWORD128(DWORD64 l,DWORD64 h) { low = l; high = h; }
	__forceinline static const DWORD128 power(intptr_t p)
	{
		if (p < 64)
			return DWORD128(((DWORD64)1) << p, 0);
		else
			return DWORD128(0, ((DWORD64)1) << (p - 64));
	}
	__forceinline static const DWORD128 power(intptr_t s, intptr_t e)
	{
		DWORD128 v(0); for (intptr_t i = s; i < e; i++)
		{
			if (i < 64)
				v.low |= ((DWORD64)1) << i;
			else
				v.high |= ((DWORD64)1) << (i - 64);
		}
		return v;
	}
	__forceinline DWORD64 lowPart() const
	{
		return this->low;
	}
	__forceinline DWORD64 highPart() const
	{
		return this->high;
	}

	__forceinline DWORD128 operator &(const DWORD128& v0) const
	{
		return DWORD128(this->low & v0.low, this->high & v0.high);
	}
	__forceinline DWORD64 operator &(DWORD64 v0) const
	{
		return this->low & v0;
	}
	__forceinline DWORD128 operator |(const DWORD128& v0) const
	{
		return DWORD128(this->low | v0.low, this->high | v0.high);
	}
	__forceinline DWORD128 operator |(DWORD64 v0) const
	{
		return DWORD128(this->low | v0, this->high);
	}
	__forceinline DWORD128 operator ^(const DWORD128& v0) const
	{
		return DWORD128(this->low ^ v0.low, this->high ^ v0.high);
	}
	__forceinline DWORD128 operator ^(DWORD64 v0) const
	{
		return DWORD128(this->low ^ v0, this->high);
	}
	__forceinline DWORD128 operator ~() const
	{
		return DWORD128(~this->low, ~this->high);
	}
	__forceinline bool operator !()
	{
		return high == 0 && low == 0;
	}
	__forceinline bool operator &&(const DWORD128& v0)
	{
		return (this->low & v0.low) != 0 || (this->high & v0.high) != 0;
	}
	__forceinline bool operator &&(const DWORD64& v0)
	{
		return (this->low & v0) != 0;
	}
	__forceinline void operator &=(const DWORD128& v0)
	{
		this->low &= v0.low; this->high &= v0.high;
	}
	__forceinline void operator &=(DWORD64 v0)
	{
		this->low &= v0; this->high = 0;
	}
	__forceinline void operator |=(const DWORD128& v0)
	{
		this->low |= v0.low; this->high |= v0.high;
	}
	__forceinline void operator |=(DWORD64 v0)
	{
		this->low |= v0;
	}
	__forceinline void operator ^=(const DWORD128& v0)
	{
		this->low ^= v0.low; this->high ^= v0.high;
	}
	__forceinline void operator ^=(DWORD64 v0)
	{
		this->low ^= v0;
	}

	__forceinline DWORD128 operator <<(intptr_t p) const
	{
		if (p < 64)
			return DWORD128(low << p, (high << p) | (low >> (64 - p)));
		else
			return DWORD128(0, low << (p - 64));
	}
	__forceinline DWORD128 operator >>(intptr_t p) const
	{
		if (p < 64)
			return DWORD128((low >> p) | (high << (64 - p)), high >> p);
		else
			return DWORD128(high >> (p - 64), 0);
	}
	__forceinline void operator <<=(intptr_t p)
	{
		if (p < 64)
		{
			high = (high << p) | (low >> (64 - p)); low <<= p;
		}
		else
		{
			high = low << (p - 64); low = 0;
		}
	}
	__forceinline void operator >>=(intptr_t p)
	{
		if (p < 64)
		{
			low = (low >> p) | (high << (64 - p)); high >>= p;
		}
		else
		{
			low = high >> (p - 64); high = 0;
		}
	}

	__forceinline bool operator ==(const DWORD128& v0)
	{
		return this->high == v0.high && this->low == v0.low;
	}
	__forceinline bool operator !=(const DWORD128& v0)
	{
		return this->high != v0.high || this->low != v0.low;
	}
protected:
	DWORD64 low, high;
};
